#include <curl_mult.h>
extern "C" {
 #include <stdio.h>
 #include <string.h>
/* somewhat unix-specific */
 #include <sys/time.h>
 #include <unistd.h>
/* curl stuff */
#include <curl/curl.h>
}
//#include <iostream>
//#include <string>
//#include <map>
#include <memory>
//using namespace::std;
static int writer(char *data, size_t size, size_t nmemb,std::string *writerData);
int writer(char *data, size_t size, size_t nmemb, string *writerData)
{
        if (writerData == NULL)
        {        
            return 0;
        }   
        int len = size*nmemb;
        writerData->append(data,len); 
        return len;
}


/*
 * Simply download two HTTP files!
*/
void curl_mult(map<string,string> *pbuffer,map <string,string> url)
{
     CURLM *multi_handle; 
     int still_running;
    multi_handle = curl_multi_init(); 
     /* keep number of running handles */
     map<string,string>::const_iterator map_it=url.begin();
     map <string,CURL * > myhandle;
     while(map_it!=url.end())
     {
     myhandle[map_it->first]=curl_easy_init();
     /* set options */
     curl_easy_setopt(myhandle[map_it->first], CURLOPT_URL, (map_it->second).c_str()); 
    /* add the individual transfers */
     curl_multi_add_handle(multi_handle,myhandle[map_it->first]); 
     curl_easy_setopt(myhandle[map_it->first], CURLOPT_WRITEFUNCTION,writer);
     /* we pass our 'chunk' struct to the callback function */
     curl_easy_setopt(myhandle[map_it->first], CURLOPT_WRITEDATA, &((*pbuffer)[map_it->first]));
     ++map_it;
    }
     /* we pass our 'chunk' struct to the callback function */
     /* we start some action by calling perform right away */
     while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running));
           while(still_running) {
                struct timeval timeout;
                int rc; /* select() return code */
                fd_set fdread;
                fd_set fdwrite;
                fd_set fdexcep;
                int maxfd;
                 FD_ZERO(&fdread);
                FD_ZERO(&fdwrite);
                FD_ZERO(&fdexcep);
                /* set a suitable timeout to play around with */
                timeout.tv_sec = 1;
                timeout.tv_usec = 0; 
                /* get file descriptors from the transfers */
                curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); 
            /* In a real-world program you OF COURSE check the return code of the
              function calls, *and* you make sure that maxfd is bigger than -1 so
             that the call to select() below makes sense! */
                rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); 
                switch(rc) {
                            case -1:
                            /* select error */
                            break;
                            case 0:
                            default:
                           /* timeout or readable/writable sockets */
                            while(CURLM_CALL_MULTI_PERFORM ==curl_multi_perform(multi_handle, &still_running));
                            break;
                           }
           } 
    curl_multi_cleanup(multi_handle); 
    //curl_easy_cleanup(http_handle);
    map<string,CURL *>::const_iterator handle_it=myhandle.begin();
    while(handle_it!=myhandle.end())
    {
        curl_easy_cleanup(handle_it->second);
        ++handle_it;
    }
  }
